package com.sbt.demo.util;

import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.alibaba.fastjson.JSONObject;

/**
 * 3des对称加密算法，可以用于反解码，由3des将原文转为byte[]，再将byte[]转为可视化的16进制字符串
 */
public class ThreeDESHex {

	private static final String Algorithm = "DESede"; // 定义 加密算法,可用 DES,DESede,Blowfish

	private static final String keyBytes = "ccnybjponls5p1kdfmx68dt1"; // 24字节密钥

	public static String encode(String sources) {
		byte[] encoded = encryptMode(keyBytes.getBytes(), sources.getBytes());
		String encodeds = bytes2HexString(encoded);
		return encodeds;
	}

	public static String decode(String target) {
		byte[] encodedFrom = hexStringToBytes(target);
		byte[] srcBytes = decryptMode(keyBytes.getBytes(), encodedFrom);
		return new String(srcBytes);
	}

	/**
	 * @param keybyte 为加密密钥，长度为24字节
	 * @param src 为被加密的数据缓冲区（源）
	 * @return
	 */
	private static byte[] encryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			// 加密
			Cipher c = Cipher.getInstance(Algorithm);
			c.init(Cipher.ENCRYPT_MODE, deskey);
			return c.doFinal(src);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @param keybyte 为加密密钥，长度为24字节
	 * @param src 为被加密的数据缓冲区（源）
	 * @return
	 */
	private static byte[] decryptMode(byte[] keybyte, byte[] src) {
		try {
			// 生成密钥
			SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

			// 解密
			Cipher c = Cipher.getInstance(Algorithm);
			c.init(Cipher.DECRYPT_MODE, deskey);
			return c.doFinal(src);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) {

		// String test = "123123123123111111111111111111111";
		// System.err.println(encode(test));
		JSONObject data = new JSONObject();
		data.put("sysId", "605258986");
		data.put("bizId", 0);
		data.put("appKey", "dtcsinwdqygw8vjqukguldafb5njhxtg");
		String  appSignature = encode(data.toJSONString());
		System.out.println(appSignature);
		
		JSONObject data2 = new JSONObject();
		data2.put("sysId", "605258986");
		data2.put("appKey", "dtcsinwdqygw8vjqukguldafb5njhxtg");
		data2.put("account", "master@oamailtest.com");
		data2.put("aliasName", "master");
		data2.put("timeStamp", "20181220172414");
		String  appSignature2 = encode(data2.toJSONString());
		System.out.println("==appSignature2=="+appSignature2);
		//单点地址
		//http://mail.chinatelecom.cn/mailinterface/inter/newWapSso?sysId=605258986&extend=0&messageid=&fromAddr=&labelid=&appSignature=FA427E26DA0E06076298FF18A1A95FA6295164020FB67536E6C83D178D0FDCAE217F1C6A61F0BA1F2FB80D977C44E82B137ECE9CE25F3012CE82A7FC684F5DEB78DDE75A27FBEBBFC52C237741F2982F9BB2ED10729A3C60654DE4B5621D00D79F01AAF511429F7EB02F9A3BF762E8DDD84EAF2CE498EE132D7992B823C61686B96F78990A781ECCEBA1B8E4368982CB5EC90BEA4AAA50E5
//		System.err
//				.println(encode(
//						"文章出处:http://my.oschina.net/chihz/blog/58057刚才无事网上瞎逛的时候看到有同学总结自己最近去面试时被问到的面试题,看到有人被问到URL的最大长度、Cookie...")
//						.length());

	}

	/**
	 * 将字节转为16进制可视化字符串
	 * 
	 * @param b
	 * @return
	 */
	private static String bytes2HexString(byte[] b) {
		String ret = "";
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			ret += hex.toUpperCase();
		}
		return ret;
	}

	/**
	 * 将字符串还原成字节
	 * 
	 * @param hexString the hex string
	 * @return byte[]
	 */
	private static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || "".equals(hexString)) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	/**
	 * Convert char to byte
	 * 
	 * @param c char
	 * @return byte
	 */
	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

}